package com.taiji.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.Map;

/**
 * @author -1
 * @since 2023/08/07 16:01
 * description:
 */
public class JwtUtil {

    /**
     * 定义密钥
     */
    private static final String secret="412$lucy%6[>?y6";

    /**
     * 生成token
     * @param payloadInfo   要存放的信息
     */
    public static String createToken(Map<String, Object> payloadInfo) {
        //1- JWT创建出一个token
        JWTCreator.Builder builder = JWT.create();
        //存入要存放的信息
        for (Map.Entry<String, Object> entry : payloadInfo.entrySet()) {
            setPayloadInfo(builder, entry.getKey(), entry.getValue());
        }
        //创建token并返还
        return builder.sign(Algorithm.HMAC256(secret));
    }

    /**
     * 对token进行校验的方法，若没抛出任何异常说明验证成功
     */
    public static void verify(String token) {
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
        jwtVerifier.verify(token);
    }

    /**
     * 从解析后的token中获取非数组类型数据
     */
    public static  <T> T getTokenValue(String token, String key, Class<T> aClass) {
        DecodedJWT decodedJWT =
                JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        return decodedJWT.getClaim(key).as(aClass);
    }

    /**
     * 从解析后的token中获取数据
     * @param token： jwtToken
     * @param key     在设置withClaim时的key
     * @param alass   要获取的数据的类型
     */
    public static  <T> T getValue(String token,String key, Class<T> alass){
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
        return decodedJWT.getClaim(key).as(alass);
    }

    /**
     判断类型
     */
    private static void setPayloadInfo(JWTCreator.Builder builder, String key, Object value) {
        Class<?> aClass = value.getClass();

        if (aClass.equals(String.class)) {
            builder.withClaim(key, (String) value);
        } else if (aClass.equals(Boolean.class)) {
            builder.withClaim(key, (Boolean) value);
        } else if (aClass.equals(Date.class)) {
            builder.withClaim(key, (Date) value);
        } else if (aClass.equals(Integer.class)) {
            builder.withClaim(key, (Integer) value);
        } else if (aClass.equals(Long.class)) {
            builder.withClaim(key, (Long) value);
        } else if (aClass.equals(Double.class)) {
            builder.withClaim(key, (Double) value);
        } else if (aClass.equals(String[].class)) {
            builder.withArrayClaim(key, (String[]) value);
        } else if (aClass.equals(Long[].class)) {
            builder.withArrayClaim(key, (Long[]) value);
        } else if (aClass.equals(Integer[].class)) {
            builder.withArrayClaim(key, (Integer[]) value);
        } else {
            throw new IllegalArgumentException("存入token中的数据不合法，存入的数据类型应为：" +
                    "String、Boolean、Date、Integer、Long、Double、String[]、Long[]、Integer[]");
        }
    }
}
